#include <QWidget>
#include <QDateTime>
#include <QKeyEvent>

#include "WPNetworkEngine.h"
#include "addpostview.h"
#include "BlogView.h"
#include "WPData.h"
#include "LocationFinder.h"
#include "imagewidget.h"
#include "utils.h"

#include "wpconfirmdialog.h"

static const char* KLocalDraft = "Local draft";

AddPostView::AddPostView(BlogView *parent) : QFrame(0), iParent(parent)
{
    ui.setupUi(this);
    ui.scrollArea->setWidget(ui.layoutWidget);
    ui.layoutWidget->setContentsMargins(5, 5, 5, 5);

    iCategoryListLength = 30; // TODO some better method

    ui.titleEdit->SetExplanation(tr("Post title"));
    ui.passwordEdit->SetExplanation(tr("Password"));
    ui.passwordEdit->SetPasswordMasking(true);
    ui.tagsEdit->SetExplanation(tr("Tags"));
    ui.contentsEdit->setExplanationText(tr("Tap to begin writing"));

    // Prepare softkeys
    QAction* leftSoftKey = new QAction(tr("Save"), this);
    connect(leftSoftKey, SIGNAL(triggered()), this, SLOT(SavePost()));
    leftSoftKey->setSoftKeyRole(QAction::PositiveSoftKey);
//    addAction(leftSoftKey);
    QAction* rightSoftKey = new QAction(tr("Cancel"), this);
    connect(rightSoftKey, SIGNAL(triggered()), this, SLOT(Cancel()));
    rightSoftKey->setSoftKeyRole(QAction::NegativeSoftKey);
//    addAction(rightSoftKey);

    connect(ui.addPhotosButton, SIGNAL(clicked(bool)), this, SLOT(AddPhotosClicked(bool)));
    connect(ui.addVideosButton, SIGNAL(clicked(bool)), this, SLOT(AddVideosClicked(bool)));
    connect(ui.categoriesEdit, SIGNAL(clicked()), this, SLOT(CategoriesClicked()));
    //connect(ui.addLocationDataBox, SIGNAL(stateChanged(int)), this, SLOT(AddLocationDataBoxClicked(int)));
    connect(ui.addLocationButton, SIGNAL(clicked()), this, SLOT(AddLocationButtonPressed()));

    connect(ui.contentsEdit, SIGNAL(showErrorNote(QString)), this, SIGNAL(ShowErrorNote(QString)));

    ui.scrollArea->DisableScrollAtWidget(ui.statusEdit->view());

    // Finally add the data for WPCustomViewBasicData
    //
    iTitleText = tr("Edit Post");
    iTabText = tr("Edit");
    iHappyAction = leftSoftKey;
    iSadAction = rightSoftKey;

#if defined(HAVE_QTM_LOCATION)
    connect(&iLocationFinder, SIGNAL(positionUpdated()),
            this, SLOT(LocationUpdated())
    );
#endif // defined(HAVE_QTM_LOCATION)
}

AddPostView::~AddPostView()
{
}

void AddPostView::NewPost(WPDataBlog *aBlog)
{
    iDataBlog = aBlog;
    iPost = new WPDataPost(*aBlog);

    // destroy old thumbnails.
    foreach (ImageWidget* thumb, iImageWidgets) {
        delete thumb;
    }
    iImageWidgets.clear();

    // XXX: refactor to ResetView(iPost)
    iCategories.clear();
    iAddedImages.clear();
    iAddedVideos.clear();
    ui.titleEdit->setText(QString());
    ui.contentsEdit->reset();
    ui.contentsEdit->setText(QString());
    ui.tagsEdit->setText(QString());
    ui.dateTimeEdit->setDateTime(iPost->GetLocalTime());
    ui.passwordEdit->setText(QString());
    ui.addPhotosButton->setText(tr("Add photos..."));
    ui.addVideosButton->setText(tr("Add videos..."));
    ui.categoriesEdit->setText(tr("Add categories..."));

    // Statuses
    ui.statusEdit->clear();
    QStringList keyList, valueList;
    QMap<QString, QString>::const_iterator i;
    for (i = aBlog->iPostStatuses.constBegin(); i != aBlog->iPostStatuses.constEnd(); i++)
    {
        keyList.append(i.key());
        valueList.append(i.value());
    }
    ui.statusEdit->addItems(valueList);
    ui.statusEdit->addItem(KLocalDraft);

#if defined(HAVE_QTM_LOCATION)
    iLocation = QtMobility::QGeoPositionInfo();
    ui.addLocationButton->resetPosition();
#else // defined(HAVE_QTM_LOCATION)
    ui.addLocationButton->setNotSupported();
#endif // defined(HAVE_QTM_LOCATION)
}

void AddPostView::EditPost(WPDataBlog *aBlog, WPPost aPost)
{
    iDataBlog = aBlog;
    iPost = aPost;

    // destroy old thumbnails.
    foreach (ImageWidget* thumb, iImageWidgets) {
        delete thumb;
    }
    iImageWidgets.clear();

    // XXX: refactor to ResetView(iPost)
    iAddedImages.clear();
    iAddedVideos.clear();
    ui.titleEdit->setText(aPost->iTitle);
    ui.contentsEdit->reset();
    ui.contentsEdit->setText(aPost->iDescription);
    ui.tagsEdit->setText(aPost->iMtKeywords);
    ui.dateTimeEdit->setDateTime(aPost->GetLocalTime());
    ui.passwordEdit->setText(aPost->iWpPassword);
    ui.addPhotosButton->setText(tr("Add photos..."));
    ui.addVideosButton->setText(tr("Add videos..."));

    // Collect categories
    iCategories = aPost->iCategories;
    ShowSelectedCategories();

    // Fill the status box, preselect the correct item
    ui.statusEdit->clear();
    QStringList keyList, valueList;
    QMap<QString, QString>::const_iterator j;
    for (j = aBlog->iPostStatuses.constBegin(); j != aBlog->iPostStatuses.constEnd(); j++)
    {
        keyList.append(j.key());
        valueList.append(j.value());
    }
    ui.statusEdit->addItems(valueList);
    if (aPost->IsLocal())
    {
        ui.statusEdit->addItem(KLocalDraft);
        ui.statusEdit->setCurrentIndex(ui.statusEdit->count() - 1);
    }
    // Using regular for loop as we need to get the index
    for (int i = 0; i < keyList.count(); ++i)
    {
        if (aPost->iStatus.compare(keyList.at(i)) == 0)
        {
            ui.statusEdit->setCurrentIndex(i);
            break;
        }
    }

#if defined(HAVE_QTM_LOCATION)
    iLocation = aPost->iLocation;
    if(iLocation.isValid()){
        ui.addLocationButton->setPosition(iLocation);
        ui.addLocationButton->setFormattedAddress("");
        emit ResolveFormattedAddress(iLocation.coordinate().latitude(), iLocation.coordinate().longitude());
    } else {
        ui.addLocationButton->resetPosition();
    }
#else // defined(HAVE_QTM_LOCATION)
    ui.addLocationButton->setNotSupported();
#endif // defined(HAVE_QTM_LOCATION)
}

void AddPostView::SavePost()
{
#if defined(HAVE_QTM_LOCATION)
    iLocationFinder.stopSearchingForLocation();
    ui.addLocationButton->setBusy(false);
#endif // defined(HAVE_QTM_LOCATION)
    if (ui.statusEdit->currentText() == KLocalDraft) {
        if (iAddedImages.count() > 0)
            emit ShowWarningNote(tr("Photos are not saved in local drafts. Please re-add photos when publishing the post."));
        
        if (iAddedVideos.count() > 0)
            emit ShowWarningNote(tr("Videos are not saved in local drafts. Please re-add videos when publishing the post."));

        // just update locally
        iPost->UpdateLocal(
            ui.titleEdit->text(),           // title
            ui.contentsEdit->text(),        // description
            ui.tagsEdit->text(),            // tags
            ui.dateTimeEdit->dateTime(),    // dateCreated
            ui.passwordEdit->text(),        // password
            iCategories                    // categories
#if defined(HAVE_QTM_LOCATION)
            , iLocation
#endif // defined(HAVE_QTM_LOCATION)
        );
    
    } else {
        // update on network
        QList<WPMediaFile> listOfMediaFiles;
        foreach(ImageWidget* image,iImageWidgets)
        {
            WPMediaFile mediaFile(image->FileName());
            mediaFile.rotationAngle = image->RotationAngle();
            mediaFile.size = image->TargetSize();
            mediaFile.alignment = image->Alignment();
            listOfMediaFiles.append(mediaFile);
        }

        foreach(QString videoFilename, iAddedVideos)
        {
            listOfMediaFiles.append(WPMediaFile(videoFilename));
        }

        iPost->UpdateStatus(
            ui.titleEdit->text(),           // title
            ui.contentsEdit->text(),        // description
            ui.tagsEdit->text(),            // tags
            ui.dateTimeEdit->dateTime(),    // dateCreated
            ui.passwordEdit->text(),        // password
            iCategories,                    // categories
            iDataBlog->iPostStatuses.key(ui.statusEdit->currentText()),     // status
            listOfMediaFiles
#if defined(HAVE_QTM_LOCATION)
	        , iLocation
#endif // defined(HAVE_QTM_LOCATION)
        );
    }

    // forget item
    iPost = NULL;

    // XXX: more generic
    iParent->ShowTabbedListView();
#ifdef Q_WS_MAEMO_5
    close();
#endif
}

void AddPostView::ImagesAdded(const QStringList& aFilenames, QList<QPixmap> aThumbnails)
{
    iAddedImages = aFilenames;

    RefreshAddPhotoText();

    // refresh image thumbnails.
    if (aFilenames.size() == aThumbnails.size())
    {
        // destroy old thumbnails.
        foreach (ImageWidget* thumb, iImageWidgets)
        {
            delete thumb;
        }
        iImageWidgets.clear();

        // add new ones.
        if (aThumbnails.size() > 0)
        {
            for(int i = 0; i < aFilenames.size(); i++)
            {
                ImageWidget* imageWidget = new ImageWidget(*iDataBlog,
                                                           aThumbnails.at(i),
                                                           aFilenames.at(i),
                                                           this);
                ui.thumbnails->addWidget(imageWidget);
                iImageWidgets.append(imageWidget);
                connect(imageWidget,SIGNAL(removeClicked(ImageWidget*)),this,SLOT(RemoveImageWidget(ImageWidget*)));
            }
            update();
        }
    }

}

void AddPostView::VideosAdded(const QStringList& aFilenames)
{
    iAddedVideos = aFilenames;

    QString labelText;
    if (iAddedVideos.size() == 0)
        labelText = tr("Add videos...");
    else if (iAddedVideos.size() == 1)
        labelText = tr("Adding 1 new video");
    else
        labelText = tr("Adding %1 new videos").arg(iAddedVideos.size());

    ui.addVideosButton->setText(labelText);
}

void AddPostView::SelectCategories (const QStringList &categories)
{
    iCategories = categories;

    // update
    ShowSelectedCategories();
}

void AddPostView::ShowSelectedCategories()
{
    QString textList;
    foreach (QString str, iCategories)
        textList += str + ", ";
    if (textList.length() > 0)
        textList = textList.mid(0, textList.length() - 2);
    else
        textList = tr("Add categories") + "...";

    if (textList.length() > iCategoryListLength)
        textList = textList.left(iCategoryListLength) + "...";
    ui.categoriesEdit->setText(textList);
}

void AddPostView::CategoriesClicked()
{
    iParent->ShowCategoryView(iCategories);
}

void AddPostView::Cancel()
{
    if(ui.titleEdit->text().length() || ui.contentsEdit->text().length()) {
        WP_CONFIRM_AND_RETURN_ON_FALSE(iParent);
    }
    
#if defined(HAVE_QTM_LOCATION)
    iLocationFinder.stopSearchingForLocation();
    ui.addLocationButton->setBusy(false);
#endif // defined(HAVE_QTM_LOCATION)

    iParent->ShowTabbedListView();
}

void AddPostView::AddPhotosClicked(bool aDummy)
{
    Q_UNUSED(aDummy)
    iParent->ShowImageList(iAddedImages, true);
}

void AddPostView::AddVideosClicked(bool aDummy)
{
    Q_UNUSED(aDummy)
    iParent->ShowVideoList(iAddedVideos, true);
}

void AddPostView::AddLocationButtonPressed()
{
#if defined(HAVE_QTM_LOCATION)
    if(!iLocation.isValid()){
        iLocationFinder.startSearchingForLocation();
        ui.addLocationButton->setBusy(true);
    } else {
        iLocation = QtMobility::QGeoPositionInfo();
        ui.addLocationButton->resetPosition();
        ui.addLocationButton->setBusy(false);
        iLocationFinder.stopSearchingForLocation();
    }
#endif // defined(HAVE_QTM_LOCATION)
}

void AddPostView::AddLocationDataBoxClicked(int newState)
{
    Q_UNUSED(newState);
}

#if defined(HAVE_QTM_LOCATION)
void AddPostView::LocationUpdated()
{
    iLocation = iLocationFinder.getCurrentPosition();
    QString address = iLocationFinder.getFormattedAddress();
    ui.addLocationButton->setPosition(iLocation);
    ui.addLocationButton->setFormattedAddress(address);
    if (address.isEmpty())
        emit ResolveFormattedAddress(iLocation.coordinate().latitude(), iLocation.coordinate().longitude());
}
#endif // defined(HAVE_QTM_LOCATION)

void AddPostView::setFocus()
{
    ui.scrollArea->ScrollToTop();
    if(Utils::smallScreen()) {
        ui.titleEdit->setFocus();
    }
}

void AddPostView::FormattedAddressResolved(qreal latitude, qreal longitude, const QString &formattedAddress)
{
#if defined(HAVE_QTM_LOCATION)
    ui.addLocationButton->setFormattedAddress(formattedAddress);
    iLocationFinder.formattedAddressResolved(latitude, longitude, formattedAddress);
#else
    Q_UNUSED(latitude); Q_UNUSED(longitude); Q_UNUSED(formattedAddress);
#endif
}

void AddPostView::RemoveImageWidget(ImageWidget *targetWidget)
{
    int index = iImageWidgets.indexOf(targetWidget);
    int fileNameIndex = iAddedImages.indexOf(targetWidget->FileName());
    if (index >= 0)
    {
        iImageWidgets.removeAt(index);
        targetWidget->hide();
        targetWidget->deleteLater();

    }
    if (fileNameIndex >= 0)
    {
        iAddedImages.removeAt(fileNameIndex);
    }
    RefreshAddPhotoText();
}


void AddPostView::RefreshAddPhotoText()
{
    QString labelText;
    if (iAddedImages.size() == 0) {
        labelText = tr("Add photos") + "...";
    } else if (iAddedImages.size() == 1) {
        labelText = tr("Adding 1 new photo");
    } else {
        labelText = tr("Adding %1 new photos").arg(iAddedImages.size());
    }
    ui.addPhotosButton->setText(labelText);
}
